package com.joymart.user.service;

import com.joymart.order.model.Order;
import com.joymart.user.model.BusinessRole;
import com.joymart.user.model.CachedUser;
import com.joymart.user.model.User;
import com.joymart.user.repo.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;

import static com.joymart.common.utils.CollectionUtils.asList;
import static org.springframework.data.relational.core.query.Query.query;

@Service
public class UserQueryService {

    @Autowired
    private UserCacheManager userCacheManager;

    @Autowired
    private JdbcAggregateTemplate jdbcAggregateTemplate;

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    public Page<CachedUser> searchNonPartyAUsers(BusinessRole businessRole, String username, String nickname, Pageable pageable){
        String where = " where party_a = false ";
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        if(!StringUtils.isEmpty(username)){
            where+=" and username = :username";
            params.put("username", username);
        }

        if(!StringUtils.isEmpty(nickname)){
            where+=" and nickname like :nickname";
            params.put("nickname", "%"+nickname+"%");
        }

        if(businessRole!=null){
            where+=" and id in (select user_id  from user_business_role where business_role =:businessRole)";
            params.put("businessRole", businessRole.name());
        }

        long count = namedParameterJdbcTemplate.queryForObject("select count (*) from \"user\" u "+ where, params, Long.class);
        if(count == 0) {
            return Page.empty();
        }else {
            params.put("limit", pageable.getPageSize());
            params.put("offset", pageable.getOffset());
            List<String> content = namedParameterJdbcTemplate.queryForList("select id from \"user\" u "+ where + " order by  id asc limit :limit offset :offset  ", params, String.class);
            return new PageImpl<>(content,pageable , count).map(userCacheManager::get);
        }
    }


    public Page<CachedUser> searchPartyAUsers( String username, String nickname, Pageable pageable) {
        Criteria criteria = Criteria.where("partyA").isTrue().and("id").not("10000");
        if(StringUtils.hasText(username)){
            criteria = criteria.and("username").is(username);
        }
        if(StringUtils.hasText(nickname)){
            criteria = criteria.and("nickname").like("%"+nickname+"%");
        }

        long count = jdbcAggregateTemplate.count(query(criteria), User.class);
        if(count == 0) {
            return Page.empty();
        }else {
            List<User> content = asList(jdbcAggregateTemplate.findAll(query(criteria).limit(pageable.getPageSize()).offset(pageable.getOffset())
                    .sort(Sort.by(Sort.Direction.ASC, "id")), User.class));
            return new PageImpl<>(content,pageable , count).map(user -> user.getId()).map(userCacheManager::get);
        }

    }
}
